<template>
  <div class="c-page-table" :class="getPageTableClass" :style="pageStyle">
    <CPageHeader
      ref="pageHeaderRef"
      v-bind="getHeaderProps"
      v-model:searchForm="localSearchForm"
      @change-tab="handleSearch"
      v-show="showPageHeader"
    >
      <template #headerRightButton>
        <slot name="headerRightButton"></slot>
      </template>
    </CPageHeader>
    <div
      class="c-page-table__body-wrapper"
      :class="[
        getProps.isContentScroll || getSidebarProps?.sidebarOption
          ? 'c-page-table__body-wrapper--overflow'
          : '',
        getSidebarProps?.sidebarOption ? 'c-page-table__body-wrapper--has-sidebar' : ''
      ]"
    >
      <PageTableSidebar
        v-bind="getSidebarProps"
        v-model:searchForm="localSearchForm"
        @change="handleSearch"
      />
      <div class="c-page-table__body">
        <div
          class="c-page-table__body-main"
          :class="getProps.isShowSearchBar ? '' : 'c-page-table__body-main--hide-search-bar'"
        >
          <CSearchBar
            ref="searchBarRef"
            v-model:searchForm="localSearchForm"
            v-model:tableFieldsSetting="localTableFieldsSetting"
            :searchOptions="getProps.searchOptions"
            :enable-fields-setting="getProps.enableFieldsSetting"
            :is-single-filter-tab="getProps.isSingleFilterTab"
            :is-show-refresh-btn="getProps.isShowRefreshBtn"
            @change="handleSearch"
            @refresh="handleRefresh"
            v-if="getProps.isShowSearchBar"
          >
            <template #placeholder>
              <slot name="searchBarPlaceholder"></slot>
            </template>
            <template #placeholderRight>
              <slot name="searchBarPlaceholderRight"></slot>
            </template>
          </CSearchBar>
          <div class="body-main__tips" v-if="$slots.headerTips">
            <slot name="headerTips"></slot>
          </div>
          <div class="body-main__table">
            <slot name="table" v-bind="getTableProps" :tableFieldsSetting="localTableFieldsSetting">
              <CTable
                ref="tableRef"
                v-bind="getTableProps"
                v-if="getTableProps && Object.keys(getTableProps).length"
                @sort-change="handleSortChange"
                @checkbox-change="handleCheckboxChange"
              >
                <template #default>
                  <slot></slot>
                  <template v-if="localTableFieldsSetting?.length">
                    <template v-for="item in localTableFieldsSetting" :key="item.key">
                      <vxe-colgroup
                        :title="item.title"
                        v-bind="getTableColumnProps(item)"
                        v-if="item.children?.length && isShowColumnGroup(item.children)"
                      >
                        <template v-for="item2 in item.children" :key="item2.key">
                          <vxe-column
                            v-bind="getTableColumnProps(item2)"
                            v-if="isShowColumn(item2)"
                          >
                            <template
                              #header="{ column, columnIndex }"
                              v-if="item2.headerSlot || item2.titleTips"
                            >
                              <slot
                                :name="item2.headerSlot"
                                :column="column"
                                :columnIndex="columnIndex"
                                v-if="item2.headerSlot"
                              />
                              <CTableColumnHeaderWithTitleTips
                                :title="item2.title"
                                :titleTips="item2.titleTips"
                              />
                            </template>
                            <template #default="scope">
                              <template v-if="item2.slot">
                                <slot :name="item2.slot" :scope="scope"></slot>
                              </template>
                              <template v-else>
                                {{
                                  item2.field
                                    ? resolveChainedFieldValue(item2.field, scope.row)
                                    : '-'
                                }}
                              </template>
                            </template>
                          </vxe-column>
                        </template>
                      </vxe-colgroup>
                      <vxe-column
                        v-bind="getTableColumnProps(item)"
                        v-else-if="!item.children?.length && isShowColumn(item)"
                      >
                        <template
                          #header="{ column, columnIndex }"
                          v-if="item.headerSlot || item.titleTips"
                        >
                          <slot
                            :name="item.headerSlot"
                            :column="column"
                            :columnIndex="columnIndex"
                            v-if="item.headerSlot"
                          />
                          <CTableColumnHeaderWithTitleTips
                            :title="item.title"
                            :titleTips="item.titleTips"
                          />
                        </template>
                        <template #default="scope">
                          <template v-if="item.slot">
                            <slot :name="item.slot" :scope="scope"></slot>
                          </template>
                          <template v-else>
                            {{ item.field ? resolveChainedFieldValue(item.field, scope.row) : '-' }}
                          </template>
                        </template>
                      </vxe-column>
                    </template>
                  </template>
                </template>
                <template #batchOperaBtns="{ selection }">
                  <slot name="batchOperaBtns" :selection="selection"></slot>
                </template>
                <template #empty>
                  <slot name="empty"></slot>
                </template>
              </CTable>
            </slot>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
export default {
  name: 'CPageTable'
};
</script>
<script lang="ts" setup>
import {
  defineProps,
  defineEmits,
  defineSlots,
  Ref,
  ref,
  watch,
  reactive,
  computed,
  unref,
  nextTick
} from 'vue';
import { CPageHeader, CPageHeaderProps } from '../../PageHeader';
import { CSearchBar } from '../../SearchBar';
import type { CPageTableProps } from './page-table';
import type { PageTableActionType } from './useCPageTable';
import { pageProps, TableFieldsSettingType } from './page-table';
import { removeUndefinedParams } from '@/utils/index';
import { CTable, CTableProps, CTableColumnHeaderWithTitleTips } from '@/components/CTable';
import PageTableSidebar from './PageTableSidebar.vue';
import { empty } from '@/utils/index';

const props: CPageTableProps = defineProps(pageProps);
const emit = defineEmits([
  'update:searchForm',
  'register',
  'sort-change',
  'refresh',
  'checkbox-change'
]);
const slots = defineSlots();
const pageHeaderRef = ref();
const tableRef = ref();
// 页面样式
const pageStyle = computed(() => {
  const style = {};
  const borderRadius = getProps.value?.radius || 0;

  if (borderRadius) {
    let radius = '';
    if (typeof borderRadius === 'number') {
      radius = borderRadius + 'px';
    } else {
      if (borderRadius.indexOf('px') > -1) {
        radius = borderRadius;
      } else {
        radius = borderRadius + 'px';
      }
    }
    Object.assign(style, {
      borderRadius: radius,
      overflow: 'hidden'
    });
  }

  return style;
});

// 页面class
const getPageTableClass = computed(() => {
  const cls: string[] = [];
  // 详情页的特殊样式
  if (getProps.value?.isDetailPage) cls.push('c-page-table--detail');
  // 详情页并且没有搜索列表的特殊样式
  if (getProps.value?.isDetailPage && !getProps.value.searchOptions?.length)
    cls.push('c-page-table--detail-small');
  return cls;
});

// all props
const innerPropsRef = ref<Partial<CPageTableProps>>();

// all props
const getProps = computed(() => {
  return { ...props, ...unref(innerPropsRef) } as CPageTableProps;
});

// header props
const getHeaderProps = computed<Omit<CPageHeaderProps, 'searchForm'>>(() => {
  const params = {
    title: unref(getProps).title,
    isBack: unref(getProps).isBack,
    descText: unref(getProps).descText,
    explainText: unref(getProps).explainText,
    // tabsList: unref(getProps).tabsList,
    // defaultActiveTab: unref(getProps).defaultActiveTab,
    searchOptions: unref(getProps).searchOptions
  };
  return removeUndefinedParams(params);
});

const getSidebarProps = computed(() => {
  const sidebarOptions = unref(getProps).searchOptions?.filter(n => n.type === 'sidebar') || [];
  return {
    sidebarOption: sidebarOptions[0]
  };
});

const showPageHeader = computed(() => {
  return unref(getProps)?.showPageHeader;
});

// table props
const getTableProps = computed<CTableProps>(() => {
  const params = unref(getProps).tableOptions as CTableProps;
  return removeUndefinedParams(params);
});

// 当前组件的searchForm
const localSearchForm = reactive(props.searchForm);

// 监听localSearchForm的变化，用于修改父组件的searchForm
watch(
  localSearchForm,
  localSearchForm => {
    console.log('searchForm数据改变', localSearchForm);
    emit('update:searchForm', localSearchForm);
  },
  {
    // 使用deep时，监听对象/数组的旧值与新值相同。
    deep: true
  }
);

// 搜索方法
function handleSearch() {
  console.log('TablePage handleSearch', localSearchForm);
  refresh(true);
}

/**
 * @Description: 刷新表格()
 * @param {*} isReset 是否重置页码
 * @return {*}
 */
function refresh(isReset = false) {
  // 如果table插槽存在就不refresh
  if (slots.table) {
    emit('refresh');
    return;
  }
  tableRef.value?.refresh(isReset);
}

function setProps(props: Partial<CPageTableProps>) {
  innerPropsRef.value = { ...unref(innerPropsRef), ...props };
  console.log('innerPropsRef', innerPropsRef.value);
}

// 重置selection选项
function resetSelection() {
  tableRef.value?.resetSelection();
}

// 获取selection选项
function getSelection() {
  return tableRef.value?.multipleSelection;
}

// 开关树的展开状态
function toggleRowExpansion(...options: any) {
  console.log('toggleRowExpansion', options);
  tableRef.value?.toggleRowExpansion(...options);
}

// 手动排序
function handleSortChange({ column, field, order }: any) {
  console.log('handleSortChange', column, field, order);
  emit('sort-change', { column, field, order });
}

function handleCheckboxChange(table: any) {
  emit('checkbox-change', table);
}
// 用于刷新searchOption的配置信息
function refreshSearchOptions(index?: number | number[]) {
  console.log('refreshSearchOptions', refreshSearchOptions);
  if (typeof index !== 'undefined') {
    pageHeaderRef.value?.refreshSearchOptions(index);
  } else {
    pageHeaderRef.value?.refreshSearchOptions();
  }
}

// 获取列表总数
const getTotal = () => {
  return tableRef.value?.totalCount || 0;
};

const clearData = () => {
  tableRef.value.dataSource = [];
};

const searchEvent = (query: string, searchEvent: string[], lazy?: boolean) => {
  tableRef.value?.searchEvent(query, searchEvent, lazy);
};

function handleRefresh() {
  if (unref(getProps).isTree) {
    // 如果是树结构，先收起全部
    tableRef.value.clearTreeExpand();
  }
  refresh();
}

function operationTable(callback: (tableRef: Ref<any>) => void) {
  tableRef.value?.operationTable(callback);
}

const pageTableAction: PageTableActionType = {
  refresh,
  setProps,
  resetSelection,
  getSelection,
  toggleRowExpansion,
  refreshSearchOptions,
  getTotal,
  clearData,
  searchEvent,
  updateTableFieldsSetting,
  operationTable
};

emit('register', pageTableAction);

/**
 * 获取列的参数
 * @param item
 */
function getTableColumnProps(item: any) {
  // console.log('getTableColumnProps', item);
  const { slot, headerSlot, ...params } = item;
  // NOTE 如果不设置overflow = false，默认增加
  if (params?.overflow !== false) {
    Object.assign(params, {
      'show-header-overflow': 'tooltip',
      'show-overflow': 'tooltip'
    });
  }
  return params;
}
/**
 * 是否显示列
 * @param item
 */
function isShowColumn(item: TableFieldsSettingType) {
  // console.log('isShowColumn', item);
  const { columnSettingConfig, enabled } = item;
  if (enabled === false) return false;
  // 没有columnSettingConfig默认显示
  if (!columnSettingConfig || columnSettingConfig?.enabled) return true;
  return false;
}

/**
 * 是否显示分组列
 * @param arr
 */
function isShowColumnGroup(arr: TableFieldsSettingType[]) {
  let flag = false;
  for (const item of arr) {
    if (isShowColumn(item)) {
      flag = true;
    }
  }
  return flag;
}

function resolveChainedFieldValue(field: string, row: any) {
  if (!field) return '-';
  if (field.indexOf('.') > -1) {
    const fields = field.split('.');
    const firstField = fields.shift()!;
    const leftField = fields.join('.');
    return resolveChainedFieldValue(leftField, row[firstField]);
  } else {
    return empty(row[field]);
  }
}

const localTableFieldsSetting = ref(getProps.value.tableFieldsSetting);

function updateTableFieldsSetting(setting: TableFieldsSettingType[]) {
  localTableFieldsSetting.value = setting;
  nextTick(() => {
    // 初始化setting的内容
    searchBarRef.value?.operationFixedButtons((fixedButtonsRef: Ref<any>) => {
      fixedButtonsRef.value?.getSourceColumnSetting();
    });
  });
}
const searchBarRef = ref();
</script>
<style lang="scss">
@use '../styles/index.scss' as *;
</style>
